using System;
using System.Globalization;
using NUnit.Framework;

namespace ValidationFramework.Tests
{
    [TestFixture]
	public class DateTimeConversionRuleAttributeTest
    {


        [Test]
        public void CheckValuesTyped()
		{
			const string expectedFormat = "expectedFormat";
			const DateTimeStyles expectedDateTimeStyles = DateTimeStyles.AllowLeadingWhite;
            var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, typeof(DateTimeFormatInfo), "CurrentInfo");
			Assert.AreEqual(expectedFormat, ruleAttribute.Format);

			var propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			var parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			var fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedFormat, propertyRule.Format);
			Assert.AreEqual(expectedFormat, parameterRule.Format);
			Assert.AreEqual(expectedFormat, fieldRule.Format);

            ruleAttribute.DateTimeStyles = expectedDateTimeStyles;
			Assert.AreEqual(expectedDateTimeStyles, ruleAttribute.DateTimeStyles);

			propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedDateTimeStyles, propertyRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, parameterRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, fieldRule.DateTimeStyles);
        }
        [Test]
        public void CheckValuesString()
		{
			const string expectedFormat = "expectedFormat";
			const DateTimeStyles expectedDateTimeStyles = DateTimeStyles.AllowLeadingWhite;
            var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, "System.Globalization.DateTimeFormatInfo, mscorlib", "CurrentInfo");
			Assert.AreEqual(expectedFormat, ruleAttribute.Format);

			var propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			var parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			var fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedFormat, propertyRule.Format);
			Assert.AreEqual(expectedFormat, parameterRule.Format);
			Assert.AreEqual(expectedFormat, fieldRule.Format);

            ruleAttribute.DateTimeStyles = expectedDateTimeStyles;
			Assert.AreEqual(expectedDateTimeStyles, ruleAttribute.DateTimeStyles);

			propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedDateTimeStyles, propertyRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, parameterRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, fieldRule.DateTimeStyles);
        }
        [Test]
        public void CheckValuesBasic()
		{
			const string expectedFormat = "expectedFormat";
			const DateTimeStyles expectedDateTimeStyles = DateTimeStyles.AllowLeadingWhite;
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat);
			Assert.AreEqual(expectedFormat, ruleAttribute.Format);

			var propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			var parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			var fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedFormat, propertyRule.Format);
			Assert.AreEqual(expectedFormat, parameterRule.Format);
			Assert.AreEqual(expectedFormat, fieldRule.Format);

            ruleAttribute.DateTimeStyles = expectedDateTimeStyles;
			Assert.AreEqual(expectedDateTimeStyles, ruleAttribute.DateTimeStyles);

			propertyRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
			parameterRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockParameterDescriptor<string>("foo"));
			fieldRule = (DateTimeConversionRule)ruleAttribute.CreateInstance(new MockFieldDescriptor<string>("foo"));

			Assert.AreEqual(expectedDateTimeStyles, propertyRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, parameterRule.DateTimeStyles);
			Assert.AreEqual(expectedDateTimeStyles, fieldRule.DateTimeStyles);
        }
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ExceptionNullType()
		{
			const string expectedFormat = "expectedFormat";
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, (Type)null, "Foo");

			ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
        }
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ExceptionNullTypeName()
		{
			const string expectedFormat = "expectedFormat";
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, (string)null, "Foo");

			ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void ExceptionEmptyTypeName()
		{
			const string expectedFormat = "expectedFormat";
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, string.Empty, "Foo");

			ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ExceptionNullPropertyName()
		{
			const string expectedFormat = "expectedFormat";
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, typeof(DateTimeFormatInfo), null);

			ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void ExceptionEmptyPropertyName()
		{
			const string expectedFormat = "expectedFormat";
			var ruleAttribute = new DateTimeConversionRuleAttribute(expectedFormat, typeof(DateTimeFormatInfo), string.Empty);

			ruleAttribute.CreateInstance(new MockPropertyDescriptor<string>("foo"));
        }


        [Test]
        public void CallAttributeTester()
        {
			AttributeTester.CheckDefaultValues<string>(new DateTimeConversionRuleAttribute(), true, true, true);
			AttributeTester.CheckNonDefaultValues<string>(new DateTimeConversionRuleAttribute(), true, true, true);
        }

    }
}